//d触发器
module d_latch(d,clk,q);
    input d;
    input clk;
    output q;

    reg q;

    always @ (d,clk)
        if(clk)
            q <= d;
endmodule
`timescale 1ns / 1ns

module d_latch_tb;
    reg clk,d;
    wire q;

    d_latch u1(.d(d),.clk(clk),.q(q));

    initial
    begin
        clk = 1;
        d <= 0;
        forever
        begin
            #60 d <= 1;//人为生成毛刺 
            #22 d <= 0;
            #2  d <= 1;
            #2  d <= 0;
            #16 d <= 0;//维持16ns的低电平，然后让它做周期性的循环
        end
    end

    always #20 clk <= ~clk;//半周期为20ns,全周期为40ns的一个信号
endmodule
//多路选择器
module data_selector41(sel,in,out);
    input [1:0] sel;
    input [3:0] in;
    output out;
    reg out;
    //若括号里均为0，则out必为0，完全可以不执行always语句
    always @(sel or in)
        begin
            case({sel[1],sel[0]})
                2'b00: out <= in[0];
                2'b01: out <= in[1];
                2'b10: out <= in[2];
                2'b11: out <= in[3];
                default: out <= 1'bx;
            endcase
        end
endmodule
//38译码器 
`timescale 1ns / 1ps        //时钟信号的精度和周期

module decoder_38(
    input [2:0] data_i,     //输入数据
    input [2:0] en_i,       //使能端，高低有效看要求，这里是0、1位低有效，2位高有效
    output reg [7:0] data_o //输出的八位数据
);
always @(*) begin
    if(en_i[0] || en_i[1] || !en_i[2])  //注意一下，译码器一般默认是低有效，所以全1相当于使能端无效
        data_o = 8'b1111_1111;
    else 
        case (data_i)
            3'b000: data_o = 8'b1111_1110;
            3'b001: data_o = 8'b1111_1101;
            3'b010: data_o = 8'b1111_1011;
            3'b011: data_o = 8'b1111_0111;
            3'b100: data_o = 8'b1110_1111;
            3'b101: data_o = 8'b1101_1111;
            3'b110: data_o = 8'b1011_1111;
            3'b111: data_o = 8'b0111_1111;
        endcase
end
endmodule
//编码器
module encoder8_3(
    input [7:0]I,
    output reg [2:0]Y
    );
    always@(I) begin
    	//从高位到低位判断出现1的位置，并进行转换
        if(I[7]==1) Y=3'b111;
        else if(I[6]==1) Y=3'b110;
        else if(I[5]==1) Y=3'b101;
        else if(I[4]==1) Y=3'b100;
        else if(I[3]==1) Y=3'b011;
        else if(I[2]==1) Y=3'b010;
        else if(I[1]==1) Y=3'b001;
        else if(I[0]==1) Y=3'b000;
        else Y=3'b000;
    end
endmodule

//计数器
    always @(posedge clk or negedge rst_n) begin  
        if(!rst_n)                               
            cnt<=4'b0;                                                  
        
        else if(cnt==4'd8)                         
            cnt<=4'b0;
        
        else 
            cnt<=cnt+1'b1;                        
    end